﻿using Sunny.FrameDecoder;
using System;
using System.Net;

namespace Sunny.Udp
{
    /// <summary>
    /// UDP Span解码数据事件类
    /// </summary>
    public ref struct UdpSpanDataEventArgs
    {
        /// <summary>
        /// 客户端
        /// </summary>
        public IPEndPoint IPEndPoint { get; }

        /// <summary>
        /// 解码器
        /// </summary>
        public BaseByteFrameDecoder Decoder { get; }

        /// <summary>
        /// 数据
        /// </summary>
        public ReadOnlySpan<byte> Value { get; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ipEndPoint">客户端</param>
        /// <param name="decoder"></param>
        /// <param name="value">数据</param>
        public UdpSpanDataEventArgs(IPEndPoint ipEndPoint, BaseByteFrameDecoder decoder, ref ReadOnlySpan<byte> value)
        {
            IPEndPoint = ipEndPoint;
            Decoder = Decoder;
            Value = value;
        }
    }

    /// <summary>
    /// 字节数组数据事件类
    /// </summary>
    /// <param name="sender">对象</param>
    /// <param name="e">字节数组数据事件类</param>
    public delegate void OnUdpSpanEventHandler(object sender, UdpSpanDataEventArgs e);

    /// <summary>
    /// UDP字节数组解码数据事件类
    /// </summary>
    public class UdpByteDataEventArgs : EventArgs
    {
        /// <summary>
        /// 客户端
        /// </summary>
        public IPEndPoint IPEndPoint { get; }

        /// <summary>
        /// 数据
        /// </summary>
        public IByteEventArgs Args { get; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ipEndPoint">客户端</param>
        /// <param name="args">数据</param>
        public UdpByteDataEventArgs(IPEndPoint ipEndPoint, IByteEventArgs args)
        {
            IPEndPoint = ipEndPoint;
            Args = args;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ipEndPoint">客户端</param>
        /// <param name="value">数据</param>
        public UdpByteDataEventArgs(IPEndPoint ipEndPoint, byte[] value)
        {
            IPEndPoint = ipEndPoint;
            Args = new ByteDataEventArgs(null, value);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ipEndPoint">客户端</param>
        /// <param name="value">数据</param>
        public UdpByteDataEventArgs(IPEndPoint ipEndPoint, Span<byte> value)
        {
            IPEndPoint = ipEndPoint;
            Args = new ByteDataEventArgs(null, value.ToArray());
        }
    }

    /// <summary>
    /// 字节数组数据事件类
    /// </summary>
    /// <param name="sender">对象</param>
    /// <param name="e">字节数组数据事件类</param>
    public delegate void OnUdpByteEventHandler(object sender, UdpByteDataEventArgs e);

    /// <summary>
    /// UDP错误事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public delegate void OnUdpSocketError(object sender, Exception e);

    internal class DecoderInfo : IDisposable
    {
        public BaseByteFrameDecoder Decoder { get; set; }
        public DateTime LastDataTime { get; set; }

        public DecoderInfo(BaseByteFrameDecoder decoder)
        {
            LastDataTime = DateTime.Now;
            Decoder = decoder;
        }

        public void Decode(byte[] data)
        {
            LastDataTime = DateTime.Now;
            Decoder.Decode(data);
        }

        public void Decode(ReadOnlySpan<byte> data)
        {
            LastDataTime = DateTime.Now;
            Decoder.Decode(data);
        }

        public void Dispose()
        {
            Decoder?.Dispose();
        }
    }
}
